/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#include <QCoreApplication>
#include <QBuffer>
#include <stdint.h>

#include "zipanalyzer.h"
#include "log.h"

namespace Wishmaster
{
	ZipAnalyzer::ZipAnalyzer()
	{
		m_eocdrSignature = QByteArray("\x50\x4b\x05\x06");
		m_cfhSignature = QByteArray("\x50\x4b\x01\x02");
	}

	ZipAnalyzer::~ZipAnalyzer()
	{
	}

	int ZipAnalyzer::probe(const QByteArray& arr)
	{
		int eocdr = arr.indexOf(m_eocdrSignature);
		if(eocdr < 0)
			return eocdr;

		uint32_t sign;
		uint32_t xynta1;
		uint16_t xynta2;
		uint16_t xynta3;
		uint32_t cdsize;
		uint32_t cdoffset;

		QBuffer buf(const_cast<QByteArray*>(&arr));
		buf.open(QIODevice::ReadOnly);
		buf.seek(eocdr);
		buf.read((char*)&sign, 4);
		buf.read((char*)&xynta1, 4);
		buf.read((char*)&xynta2, 2);
		buf.read((char*)&xynta3, 2);
		buf.read((char*)&cdsize, 4);
		buf.read((char*)&cdoffset, 4);
		int firstfile = arr.indexOf(m_cfhSignature, eocdr);
		if(firstfile < -1)
			return 0;
		if(xynta2 != xynta3)
			return 0;
		return eocdr;
	}
	
	ExtraInfo ZipAnalyzer::obtain(const QByteArray& arr)
	{
		ExtraInfo info;
		int eocdr = arr.indexOf(m_eocdrSignature);
		uint32_t sign;
		uint32_t xynta1;
		uint16_t xynta2;
		uint16_t xynta3;
		uint32_t cdsize;
		uint32_t cdoffset;

		QBuffer buf(const_cast<QByteArray*>(&arr));
		buf.open(QIODevice::ReadOnly);
		buf.seek(eocdr);
		buf.read((char*)&sign, 4);
		buf.read((char*)&xynta1, 4);
		buf.read((char*)&xynta2, 2);
		buf.read((char*)&xynta3, 2);
		buf.read((char*)&cdsize, 4);
		buf.read((char*)&cdoffset, 4);

		uint32_t firstfileoffset;
		int firstfile = arr.indexOf(m_cfhSignature, cdoffset);
		int delta = firstfile - cdoffset;
		buf.seek(firstfile + 42);
		buf.read((char*)&firstfileoffset, 4);
		info.data = arr.mid(firstfileoffset + delta);
		info.id = "zip";
		info.position = firstfile;
		info.description = qApp->translate("ZipAnalyzer", "This image contains a ZIP archive with %1 files.").arg(xynta2);
		info.fileext = "zip";
		info.type = "Zip archive";
		info.saveable = true;
		return info;
	}
}

